package br.com.ebc.icontatos.boundary;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.convert.Converter;
import javax.faces.model.SelectItem;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.sun.org.apache.bcel.internal.generic.GETSTATIC;

import br.com.ebc.icontatos.converter.PaisConverter;
import br.com.ebc.icontatos.jdbcconnection.DBGrupoEnvioDAO;
import br.com.ebc.icontatos.model.Cidade;
import br.com.ebc.icontatos.model.Endereco;
import br.com.ebc.icontatos.model.Estado;
import br.com.ebc.icontatos.model.Evento;
import br.com.ebc.icontatos.model.Pais;
import br.com.ebc.icontatos.repository.CidadeRepository;
import br.com.ebc.icontatos.repository.EstadoRepository;
import br.com.ebc.icontatos.repository.EventoRepository;
import br.com.ebc.icontatos.repository.PaisRepository;

@Controller("eventoManagedbean")
@Scope("session")
public class EventoManagedbean extends AbstractFormManagedbean{
	
	@Resource
	private EventoRepository eventoDAO;
	@Resource
	private PaisRepository paisDAO;
	@Resource
	private EstadoRepository estadoDAO;
	@Resource
	private CidadeRepository cidadeDAO;
	private Evento evento = new Evento();
	private Evento visualizar = new Evento();
	private Evento editar = new Evento();
	private Endereco endereco = new Endereco();
	private Pais pais = new Pais();
	private Estado estado = new Estado();
	private Cidade cidade = new Cidade();
	private String numero;
	private HtmlDataTable eventoHDT = new HtmlDataTable();
	private List<Evento> eventos = new ArrayList<Evento>();
	private List<SelectItem> objetosEstados = new ArrayList<SelectItem>();
	private List<SelectItem> objetosCidades = new ArrayList<SelectItem>();
	private int indice;
	
	public EventoManagedbean() { 
		super();
		try{
			iniciarEstados();
			iniciarCidades();
		} catch (NullPointerException e) {
			e.printStackTrace();
		}
	}

	/**
	 * metodo que limpa e cria uma nova lista de estados
	 */
	private void iniciarEstados() {
		getObjetosEstados().clear();
		getObjetosEstados().add(new SelectItem(null, "-- Selecione --"));
	}
	
	/**
	 * metodo que limpa e cria uma nova lista de cidades
	 */
	private void iniciarCidades(){
		getObjetosCidades().clear();
		getObjetosCidades().add(new SelectItem(null, "-- Selecione --"));
	}
	
	/**
	 * @return
	 * metodo para listar todos os eventos 
	 */
	@SuppressWarnings("unchecked")
	@PostConstruct
	public List<Evento> listarEventos(){
		eventos = eventoDAO.todos();
		totalContatos();
		return eventos;
	}
	
	public void totalContatos(){
		for(int i = 0; i < eventos.size(); i++){
			getEvento().setTotalContatos(eventos.get(i).getContatos().size());
		}
	}
	
	public String cadastrarEvento(){
		getEndereco().setNumero(Integer.parseInt(getNumero()));
		getEvento().setEndereco(getEndereco());
		eventoDAO.salvar(getEvento());
		return "sucesso";
	}
	
	public String atualizarEvento(){
		eventoDAO.atualizar(getEditar());
		return "sucesso";
	}
	
	/**
	 * @return
	 * metodo para excluir o evento selecionado
	 */
	public String excluirEvento(){
		eventoDAO.excluir((Evento) getEventoHDT().getRowData());
		return null;
	}
	
	/**
	 * metodo para visualizar o evento selecionado
	 */
	public void visualizarEvento(){
		setVisualizar((Evento) getEventoHDT().getRowData());
	}

	/**
	 * metodo para editar o evento
	 * e mostrar o conteudo para o usuario visualizar os campos preenchidos  
	 */
	public String editarEvento(){
		setEditar((Evento) getEventoHDT().getRowData());
		setPais(getEditar().getEndereco().getCidade().getEstado().getPais());
		carregarEstados();
		getEstado().setNomeEstado(getEditar().getEndereco().getCidade().getEstado().getNomeEstado());
		carregarCidades();
		getCidade().setNomeCidade(getEditar().getEndereco().getCidade().getNomeCidade());
		setEndereco(getEditar().getEndereco());
		setNumero(String.valueOf(getEditar().getEndereco().getNumero()));
		return "editar";
	}
	
	public String redirect(){
		return "novo";
	}
	
	public String voltar(){
		return "voltar";
	}
	
	/**
	 * @return
	 * metodo que preenche a combo de pais
	 * crio uma lista de paises que recebe todo os paises 
	 * crio uma lista de itens
	 * insiro o selecione com valor nulo
	 * e um looping para preencher com o nome a lista de itens
	 */
	@SuppressWarnings("unchecked")
	public List<SelectItem> getObjetosPaises(){
		List<Pais> paises = paisDAO.todos();
		List<SelectItem> itens = new ArrayList<SelectItem>();
		itens.add(new SelectItem(null, " -- Selecione -- "));
		for(Pais obj : paises){
			itens.add(new SelectItem(obj, obj.getNomePais()));
		}
		return itens;
	}
	
	/**
	 * metodo para carregar os estados
	 * verifico se o pais esta nulo
	 * limpo e crio uma nova lista de objetos de estado
	 * busco os estados referentes aquele pais
	 * preencho a lista de estados cde acordo com o pais selecionado
	 * caso o pais for nulo 
	 * limpo e crio uma nova lista de objetos para estado e cidade 
	 */
	public void carregarEstados(){  
		try{
			if(getPais() != null){
				iniciarEstados();
				List<Estado> estados = estadoDAO.findEstados(getPais());
				for(Estado obj : estados){
					objetosEstados.add(new SelectItem(obj.getNomeEstado()));
				}
			} else {
				iniciarEstados();
				iniciarCidades();
			}
		} catch (NullPointerException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * metodo que carrega as cidades
	 * seto o estado de acordo com o selecionado
	 * verifico se o estado esta nulo
	 * limpo e crio uma nova lista de cidades
	 * preencho a lista de cidades de acordo com o estado selecionado
	 * caso o estado for nulo
	 * limpo e crio uma nova lista de objetos para o estado e cidade
	 */
	public void carregarCidades(){
		try {
			if(!getEstado().getNomeEstado().equals("")){
				setEstado(estadoDAO.findEstado(getEstado().getNomeEstado()));
				iniciarCidades();
				List<Cidade> cidades = cidadeDAO.findCidades(getEstado());
				for(Cidade obj : cidades){
					objetosCidades.add(new SelectItem(obj.getNomeCidade()));
				}
			} else {
				iniciarEstados();
				iniciarCidades();
			}
		} catch (NullPointerException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * @return
	 * metodo que converter o objeto para string e vice-versa
	 */
	public Converter getPaisConverter(){
		PaisConverter converter = new PaisConverter();
		converter.setPaisDAO(paisDAO);
		return converter;
	}
	
	public EventoRepository getEventoDAO() {
		return eventoDAO;
	}

	public void setEventoDAO(EventoRepository eventoDAO) {
		this.eventoDAO = eventoDAO;
	}

	public Evento getEvento() {
		return evento;
	}

	public void setEvento(Evento evento) {
		this.evento = evento;
	}

	public List<Evento> getEventos() {
		return eventos;
	}

	public void setEventos(List<Evento> eventos) {
		this.eventos = eventos;
	}

	public HtmlDataTable getEventoHDT() {
		return eventoHDT;
	}

	public void setEventoHDT(HtmlDataTable eventoHDT) {
		this.eventoHDT = eventoHDT;
	}

	public List<SelectItem> getObjetosEstados() {
		return objetosEstados;
	}
	
	public void setObjetosEstados(List<SelectItem> objetosEstados) {
		this.objetosEstados = objetosEstados;
	}

	public List<SelectItem> getObjetosCidades() {
		return objetosCidades;
	}

	public void setObjetosCidades(List<SelectItem> objetosCidades) {
		this.objetosCidades = objetosCidades;
	}

	public Pais getPais() {
		return pais;
	}

	public void setPais(Pais pais) {
		this.pais = pais;
	}

	public Estado getEstado() {
		return estado;
	}

	public void setEstado(Estado estado) {
		this.estado = estado;
	}

	public Cidade getCidade() {
		return cidade;
	}

	public void setCidade(Cidade cidade) {
		this.cidade = cidade;
	}

	public Endereco getEndereco() {
		return endereco;
	}

	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}

	public String getNumero() {
		return numero;
	}

	public void setNumero(String numero) {
		this.numero = numero;
	}

	public int getIndice() {
		return indice;
	}

	public void setIndice(int indice) {
		this.indice = indice;
	}

	public Evento getVisualizar() {
		return visualizar;
	}

	public void setVisualizar(Evento visualizar) {
		this.visualizar = visualizar;
	}

	public Evento getEditar() {
		return editar;
	}

	public void setEditar(Evento editar) {
		this.editar = editar;
	}

}